-----------------------------------------------------------------------------
-- VC-IP: virtual-channel of input port:
-- Revisions:
-- 14.06.07: The control of the mux-shifter was changed from the header_req to
--           data_out[lsb-type]. In this way shift is performed immidiately with data
--           propagation through the sampling data latch. 

library ieee;
 use ieee.std_logic_1164.all;
 use ieee.std_logic_unsigned.all;

-- synopsys translate_off
-- synthesis translate_off
--library csx_HRDLIB_FTSM;
-- use csx_HRDLIB_FTSM.VCOMPONENTS.all;
-- synthesis translate_on
-- synopsys translate_on

library work;
 use work.router_pack.all;


-------------------------------------------------------------------------------
entity ssl_ip_top is
-------------------------------------------------------------------------------
port( 
      -- General Control: --
      RESET     : in  std_logic;  -- Active  

      -- External input i/f: --
      RI        : in  std_logic;
      AI        : out std_logic;
      DATAI     : in  std_logic_vector(flit_width_con-1 downto 0); -- Service level is indicated by instantiation index, input VC indication is obsolete at this stage

      -- Internal output i/f: --
      RO_H_ARR  : out std_logic_vector(num_of_ports_con-1 downto 0);
      RO_BT_ARR : out std_logic_vector(num_of_ports_con-1 downto 0);
      AO_ARR    : in  std_logic_vector(num_of_ports_con-1 downto 0);

      DO        : out std_logic_vector(flit_width_con-1 downto 0)
);           
-------------------------------------------------------------------------------
end ssl_ip_top ;
-------------------------------------------------------------------------------

-------------------------------------------------------------------------------
architecture ssl_ip_top_arch of ssl_ip_top is
-------------------------------------------------------------------------------

component latch_ctrl3 
port( 
      -- General Control: --
      RESET  : in  std_logic;  -- Active  

      -- External input i/f: --
      RI     : in  std_logic;
      AI     : out std_logic;

      -- Latch control i/f: --
      LDO    : out std_logic;
      DI     : in  std_logic;

      -- Internal output i/f: --
      RO     : out std_logic;
      AO     : in  std_logic
); 
end component;

component delay_line
generic(
   num_of_buffers : integer := 1
);
port( 
      DI  : in   std_logic;   
      DO  : out  std_logic   
);           
end component;

component lachq1  -- latch with clear (act. low) and enable (active high).
port(
      E                              :	in    std_logic;
      D                              :	in    std_logic;
      CDN                            :	in    std_logic;
      Q                              :	out   std_logic
);
end component;

component lanlq1 -- data latch with enable active low and single output.
port(
      EN                             :	in    std_logic;
      D                              :	in    std_logic;
      Q                              :	out   std_logic
);
end component;

component an02d1
port(
      A1                             :	in    std_logic;
      A2                             :	in    std_logic;
      Z                              :	out   std_logic
);
end component;

component an12d1
port(
      A1                             :	in    std_logic;
      A2                             :	in    std_logic;
      Z                              :	out   std_logic
);
end component;


signal sig_high : std_logic;

signal reset_not         : std_logic;
 
signal ldo, ldo_not, di, latch_req, ack_out, header_req, body_or_tail_req, header_req_not, header_req_del : std_logic;

signal op_idx_latch : std_logic_vector(1 downto 0);

signal data_out     : std_logic_vector(flit_width_con-1 downto 0);

signal header_req_del_rtl : std_logic;

signal ack_out_del_rtl : std_logic;

begin

sig_high <= '1';

reset_not <= not RESET;

u_latch_ctrl3: latch_ctrl3 
port map( 
      RESET  => RESET,    

      RI     => RI,
      AI     => AI,

      LDO    => ldo,
      DI     => di,

      RO     => latch_req,
      AO     => ack_out_del_rtl --ack_out
); 

-- a. Flit Type Check: --
--header_req <= '1' when ( (conv_integer(data_out(flit_type_format_h downto flit_type_format_l))=head_type_con) and (latch_req='1') ) else '0';
--
--body_or_tail_req <= '1' when ( ( (conv_integer(data_out(flit_type_format_h downto flit_type_format_l))=body_type_con) or 
--                                 (conv_integer(data_out(flit_type_format_h downto flit_type_format_l))=tail_type_con) )
--                               and (latch_req='1') ) else '0';


-- LSB: 1-header/0-not header
u_and_header_req : an02d1
port map(
      A1       => data_out(flit_type_format_l),
      A2       => latch_req,
      Z        => header_req
);

u_and_body_or_tail_req : an12d1
port map(
      A1     => data_out(flit_type_format_l), -- inverted
      A2     => latch_req,
      Z      => body_or_tail_req
);


--header_req_not <= not header_req;

-- 05.06.07: no need in this latch any more -- body request do not use it and
--           the data inside the data register is not changed until ACK- comes in.
-- b. OP Index Latch: --
--kk_op_idx_latch0: lachq1
--port map(
--      E                              => header_req, --header_req_not,
--      D                              => data_out(addr_format_l),
--      CDN                            => reset_not,
--      Q                              => op_idx_latch(0)
--);
--
--
--kk_op_idx_latch1: lachq1
--port map(
--      E                              => header_req, --header_req_not,
--      D                              => data_out(addr_format_h),
--      CDN                            => reset_not,
--      Q                              => op_idx_latch(1)
--);

-- Bypassing the latch: --
op_idx_latch(0) <= data_out(addr_format_l);
op_idx_latch(1) <= data_out(addr_format_h);



-- c. Data Latch and out shift mux: --
--ldo_not <= not ldo;


data_latch_gen: for i in 0 to (flit_width_con-1) generate
  
 data_latch: lanlq1
 port map(
      D     => DATAI(i),
      EN    => ldo,
      Q     => data_out(i)
 );
 
end generate;

-- Shift for Header.
DO <= (data_out(flit_type_format_h downto flit_type_format_l) & data_out(addr_format_l-1 downto 0) & "00") 
       when ( data_out(flit_type_format_l)='1' ) else data_out;
--     when ( header_req='1' ) else data_out; -- removed on 14.06.07:

-- 05.06.07: no need in this latch any more -- body request do not use it and
--           the data inside the data register is not changed until ACK- comes in.
-- d. Header Request delay element: --
--u_adelay_line_header_ro: delay_line
--generic map(
-- num_of_buffers => delay_line_length_con
--)
--port map( 
--      DI  => header_req,    
--      DO  => header_req_del_rtl --header_req_del 
--);        
header_req_del_rtl <= header_req; -- bypass the old delay line


-- e. ack_out: --
--ack_out_mux_proc: process(AO_ARR, op_idx_latch)
--begin
-- case op_idx_latch is
--  when "00" =>
--   ack_out <= AO_ARR(0);
--  when "01" =>
--   ack_out <= AO_ARR(1);
--  when "10" =>
--   ack_out <= AO_ARR(2);
--  when "11" =>
--   ack_out <= AO_ARR(3);
--  when others =>
--   ack_out <= AO_ARR(0);
-- end case;
--end process;

-- 11.04.07: Reuven: Acknowelege can be ORed inside SSL-IP since only one OP will return acknowelege to the certain VC. 
ack_out <= AO_ARR(0) or AO_ARR(1) or AO_ARR(2) or AO_ARR(3);


-- Timing assumption for RTL simulation:
-- The path from the req to OP-VC to latching is shorter then to ack->IP->data removal.
ack_out_del_rtl <= transport ack_out after 650 ps;

-- In RTL simulation IP-OP handshake is faster than gate singnal of VCAC SPA
-- The circuit assumes TA about this relation, here we insert some simulative 
-- delay to comply with this TA. This delay is employed only in RTL simulation
-- and is removed in synthesis. 
header_req_del <= transport header_req_del_rtl after 20 ps;

-- f. header request out: --
header_out_mux_proc: process(header_req_del, op_idx_latch)
begin
 -- Default: --
 RO_H_ARR <= (others=>'0');

 case op_idx_latch is
  when "00" =>
   RO_H_ARR(0) <= header_req_del; 
  when "01" =>                   
   RO_H_ARR(1) <= header_req_del; 
  when "10" =>                   
   RO_H_ARR(2) <= header_req_del; 
  when "11" =>
   RO_H_ARR(3) <= header_req_del; 
  when others =>
   RO_H_ARR(0) <= header_req_del; 
 end case;
end process;


-- g. body request out: --
--body_or_tail_req_out_mux_proc: process(body_or_tail_req, op_idx_latch)
--begin
-- -- Default: --
-- RO_BT_ARR <= (others=>'0');
--
-- case op_idx_latch is
--  when "00" =>
--   RO_BT_ARR(0) <= body_or_tail_req;
--  when "01" =>
--   RO_BT_ARR(1) <= body_or_tail_req;
--  when "10" =>
--   RO_BT_ARR(2) <= body_or_tail_req;
--  when "11" =>
--   RO_BT_ARR(3) <= body_or_tail_req;
--  when others =>
--   RO_BT_ARR(0) <= body_or_tail_req;
-- end case;
--end process;

-- 11.04.07: BT can be broadcasted to all OP-VC, since OP-VC monitors only the BT
--           request that is inidicated by IP-Index stored in the OP address latch.
RO_BT_ARR <= (others=>body_or_tail_req);

-------------------------------------------------------------------------------
end ssl_ip_top_arch;
-------------------------------------------------------------------------------                 

   
-------------------------------------------------------------------------------
configuration  ssl_ip_top_cfg  of ssl_ip_top is
-------------------------------------------------------------------------------
   for ssl_ip_top_arch
   end for;
-------------------------------------------------------------------------------
end  ssl_ip_top_cfg;              
-------------------------------------------------------------------------------
                 